/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tablut;
import java.io.*;
import java.net.*;
import java.util.*;

//This is the class that runs the game

public class ServeurJeuThread extends Thread {

        private Socket socket[];
        private PrintWriter[] out;
        private BufferedReader[] in;
        private String couleur[] = {"Egalité", "Blanc", "Noir"};
        private ReglesTablut instanceJeu = null;
        private long[] totalTime;
        private PrintStream localStreamOut = null;


        public ServeurJeuThread(Socket client1, Socket client2, PrintStream streamOut, boolean applet) {
                super("ServeurJeuThread");
                localStreamOut = streamOut;
                socket = new Socket[2];
                socket[0] = client1;
                socket[1] = client2;
                out = new PrintWriter[2];
                in = new BufferedReader[2];
                instanceJeu = new ReglesTablut(applet);
                totalTime = new long[2];
                totalTime[0] = 0;
                totalTime[1] = 0;
                System.out.println("Jeu lancé");
        }

        public void run(){
                int i, joueur, departLigne, departColonne, arriveeLigne, arriveeColonne;
                String input;

                try {

                        // Initialisation des E/S avec les deux clients
                        for (i = 0; i < 2; i++) {
                                out[i] = new PrintWriter(socket[i].getOutputStream(), true);
                                in[i] = new BufferedReader(new InputStreamReader(socket[i].getInputStream()));
                        }
                        // on envoie l'information de la couleur pour les clients
                        for (i = 0; i < 2; i++) {
                                out[i].println(couleur[i+1] + '\0');
                                out[i].flush();
                        }
                        sleep(2000);
                        try { // On fixe le temps maximum pour lire la socket
                                socket[0].setSoTimeout(instanceJeu.getTempsMaximum()*1000);
                                socket[1].setSoTimeout(instanceJeu.getTempsMaximum()*1000);
                        }
                        catch (SocketException e) {
                                System.out.println(e);
                        }
                        do {
                                // On récupère qui doit jouer en prochain
                                joueur = instanceJeu.getJoueur();

                                // On envoie les informations aux deux joueurs
                                for (i = 0; i < 2; i++) {
                                        out[i].println("JOUEUR "+ couleur[joueur] + '\0');
                                        out[i].flush();
                                }
                                try {
                                        sleep(500);
                                        instanceJeu.printPlateau();
                                        System.out.println("[INFO] Attente du mouvement du joueur " + couleur[joueur]);
                                        // On impose une attente max sur la lecture...
                                        socket[joueur-1].setSoTimeout((instanceJeu.getTempsMaximum()+30)*1000 - (int)totalTime[joueur-1]);
                                        // On lit le mouvement du joueur considéré
                                        long waitingTime1 = new Date().getTime();
                                        try {
                                                input = in[joueur-1].readLine();
                                        } catch (SocketException e){
                                                instanceJeu.gameOver(joueur, 10);
                                                System.out.println("[ARBITRE] Dépassement de temps sur lecture de socket");
                                                break;
                                        }
                                        long waitingTime2 = new Date().getTime();
                                        long waitingTime = waitingTime2-waitingTime1;
                                        totalTime[joueur-1] += waitingTime;
                                        System.out.println("[MOUVEMENT] " + waitingTime + " " + totalTime[joueur-1] + " "+ couleur[joueur]+" "+input);
                                        if (totalTime[joueur-1] / 1000 > instanceJeu.getTempsMaximum()) {
                                                instanceJeu.gameOver(joueur, 10);
                                                System.out.println("[ARBITRE] Dépassement du temps pour  " + joueur + ": " + (totalTime[joueur-1] / 1000) +
                                                                " secondes de réflexion !");
                                                break;

                                        }
                                        // On extirpe le mouvement depuis le message texte
                                        StringTokenizer st = new StringTokenizer(input, " \n\0");
                                        departLigne = Integer.parseInt(st.nextToken());
                                        departColonne = Integer.parseInt(st.nextToken());
                                        arriveeLigne = Integer.parseInt(st.nextToken());
                                        arriveeColonne = Integer.parseInt(st.nextToken());

                                        // on prend en compte le mouvement
                                        instanceJeu.executeMouvement(departLigne, departColonne, arriveeLigne, arriveeColonne);

                                        // broadcast the move to the other player
                                        String mouvement = "MOUVEMENT " + departLigne + " " + departColonne + " " +
                                        arriveeLigne + " " + arriveeColonne + '\0';
                                        if (joueur == 1) {
                                                out[1].println(mouvement);
                                                out[1].flush();
                                        } else {
                                                out[0].println(mouvement);
                                                out[0].flush();
                                        }
                                }
                                catch (InterruptedIOException e) {
                                        // the current player has timed out, so make the other one a winner
                                        instanceJeu.gameOver(joueur, 10);
                                        System.out.println("[ARBITRE] TIMEOUT " + joueur + '\0');
                                }
                                catch (InterruptedException e) {
                                        System.out.println(e);
                                }
                        } while(!instanceJeu.getGameOver());

                        // broadcast the winner to both player
                        for (i = 0; i < 2; i++) {
                                out[i].println("FIN! " + couleur[instanceJeu.getGagnant()] + "\0");
                                out[i].flush();
                        }
                        System.out.println("[ARBITRE] FIN! " + couleur[instanceJeu.getGagnant()] + "\0");

                        sleep(100);
                        ServeurJeu.listening = false;

                }
                catch(IOException e) {
                        System.out.println("La communication ne passe pas !");
                }
                catch (InterruptedException e) {
                        System.out.println(e);
                }
        }
}

